﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Text.RegularExpressions;

namespace FileMover.Service.Filters
{
    public class RegExFilterFactory : FilterFactoryBase<RegExFilter>
    {
        public override string ToString()
        {
            return "Regular Expression"; ///TODO: Localize
        }

        protected override string XmlLocalName
        {
            get { return "RegEx"; }
        }
        protected override string XmlNameSpace
        {
            get { return Model.mgr.LookupNamespace("FileMover"); }
        }
    }

    public class RegExFilter : RuleItemBase, IFilter
    {
        public UsageEnum Usage { get; set; }

        public string Test { get; set; }
        public string FieldName { get; set; }

        private System.Text.RegularExpressions.Regex _regex;
        List<KeyValuePair<string, string>> _vars;
        public override void FromXml(XmlElement elem)
        {
            base.FromXml(elem);
            Usage = UsageEnum.Unknown;
            Test = elem.GetAttribute("test");
            FieldName = elem.GetAttribute("value");

            var outcome = elem.GetAttribute("outcome");
            if (string.IsNullOrEmpty(outcome))
            {
            }
            else if (string.Equals(outcome, "include"))
            {
                Usage = UsageEnum.Include;
            }
            else if (string.Equals(outcome, "exclude"))
            {
                Usage = UsageEnum.Exclude;
            }
            else
            {
                throw new XmlException(string.Format("RegExFilter->outcome attribute has an invalid value: {0}", outcome));
            }

            _regex = new System.Text.RegularExpressions.Regex(Test);

            _vars = new List<KeyValuePair<string, string>>();
            foreach (XmlElement varElem in elem.SelectNodes("FileMover:Var", Model.mgr))
            {
                var name = varElem.GetAttribute("name");
                var value = varElem.GetAttribute("value");

                _vars.Add(new KeyValuePair<string, string>(name, value));
            }

        }

        public override string DisplayString()
        {
            return string.Format("Filter: Match Regular Expression {0} to field {1}", Test, FieldName);
        }



        #region IFilter Member

        public void Filter(ILog log, IItem item)
        {
            var value = item.GetProperty(FieldName);
            if (string.IsNullOrEmpty(value))
                return;

            var match = _regex.Match(value);
            if (!match.Success)
                return;
            if (Usage != UsageEnum.Unknown) item.Usage = Usage;

            foreach (var kv in _vars)
            {
                var varValue = kv.Value;
                List<string> linearArguments = new List<string>(match.Groups.Count);
                for (var i = 0; i < match.Groups.Count; ++i) linearArguments.Add(match.Groups[i].Value);

                varValue = ItemHelper.ResolveVars(item, varValue, linearArguments);
                item.SetProperty(kv.Key, varValue);
            }
            //throw new NotImplementedException();
        }

        #endregion
    }
}
